home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / ascutils.zip / PREFIX.ASM < prev    next >
Assembly Source File  |  1988-05-24  |  7KB  |  235 lines

  1. PAGE 55,130
  2. ;                   PREFIX
  3. ;  This    program    accepts    a quoted string    from the command line and prefixes
  4. ;   it to each line received from std in,  writing it to std out.
  5. ;   DOS    I/O redirection    is used    to modify files.  Input line length is
  6. ;   limited to 255 chars, prefix to 80 chars.  Output line length is limited
  7. ;   to 335 ( 255 + 80 ).  These limits may be altered by changing the 
  8. ;   equates below.
  9. ;
  10.  
  11. pfx_len        equ    050h    ; prefix buffer area    
  12. ibuf_len    equ    0100h    ; input buffer area
  13. obuf_len    equ    0150h    ; output buffer area
  14. stk_len        equ    0100h    ; program stack area
  15. total_buflen    =    pfx_len + ibuf_len + obuf_len + stk_len
  16.  
  17.  
  18. codeseg        segment
  19.         assume    cs:codeseg, ds:codeseg
  20.  
  21.         org    0100h
  22.  
  23. prefix        proc    far
  24. start:        jmp    init
  25.  
  26. ; ---------------------------------
  27. msg1        db    13, 10,    'Usage is: PREFIX <quoted string>', 13,    10, '$'
  28. msg2            db      13, 10, 'Unable to allocate memory - aborting.'
  29.                 db      13, 10, '$'
  30. ; ---------------------------------
  31.  
  32. init:           mov     bx,offset pgm_end
  33.                 add     bx,0Fh
  34.                 mov     cl,4
  35.                 shr     bx,cl
  36.                 mov     ah,04Ah         ; allocate memory explicitly
  37.                 int     021h
  38.                 mov     dx,offset msg2  ; set up error message
  39.                 jc      err_exit        ; quit if cf=1
  40.                 xor     ax,ax                   ; init buffers and stk
  41.                 mov     di,offset last_line    ;  to all 0's
  42.                 mov     cx,total_buflen
  43.                 shr     cx,1
  44.                 cld
  45.                 rep     stosw
  46.                 mov     sp,offset pgm_end
  47.  
  48.                 mov     si,81h          ; point si to command line parms
  49.                 call    get_prefix    ; get the quoted suffix string
  50.                 mov     dx,offset msg1  ; set up other error msg
  51.                 cmp     al,5            ; success code
  52.                 jne     err_exit        ; unsuccessful - quit with err msg
  53.                 call    get_prefix      ; This checks for extra stuff on
  54.                 mov     dx,offset msg1
  55.                 cmp     al,3            ;  the command line, and quits with
  56.                 jne     err_exit        ;  error msg if found.
  57.  
  58. main:        call    get_line    ; input    a line from std    in
  59.         jc    quit        ;  quit    on carry set (eof or error)
  60.         call    set_prefix    ; prefix it
  61.         call    out_put        ; output it to std out
  62.         jc    quit        ;  quit on error.
  63.         jmp    main        ; repeat until eof(input)
  64.  
  65. err_exit:       mov     di,dx
  66.                 mov     cx,0FFh
  67.                 mov     al,024h
  68.                 cld
  69.                 repnz   scasb           ; this was to get len of message
  70.                 dec     di
  71.                 mov     cx,di
  72.                 sub     cx,dx           ; some arithmetic
  73.                 mov     bx,2            ; handle for std error
  74.                 mov     ah,040h         ; output msg to std error
  75.                 int     021h            ;  (error msg will go to con)
  76.                 mov     al,1            ; exit status = 1
  77. quit:           mov     ah,04Ch
  78.                 int     021h            ; terminate process.
  79.  
  80. prefix        endp
  81.  
  82. ; ----------------------------------------------------------------------------
  83. ;        SUBROUTINE  get_prefix
  84. ;        get the    quoted prefix into the holding area
  85. ;
  86.  
  87. get_prefix    proc    near
  88.         call    rem_space        ; eat up blanks    on cmd line
  89.         mov    di,si            ; save si in di
  90.         cmp    byte ptr [si],0Dh    ; see if we have eoln
  91.         jne    Q1            ; no, continue
  92.         mov    al,3            ;  else    return eoln code.
  93.         ret
  94.  
  95. Q1:        mov    dl,022h            ; double quote
  96.         cmp    [si],dl
  97.         je    P1            ; ok, continue
  98.         mov    dl,027h            ; single quote
  99.         cmp    [si],dl
  100.         je    P1            ; still    ok, continue
  101.         mov    al,4            ; no, return non-quote code.
  102.         ret
  103.  
  104. P1:        inc    si        ; now get quoted string    into vacant
  105.         mov    di,offset last_line    ; prefix buffer    area
  106.  
  107. Q2:        lodsb            ; get [si] into    al
  108.         cmp    al,dl        ; check    for matching quote, still in
  109.         je    Q3        ; dl.  If found, we're done.
  110.         cmp    al,0Dh        ; check    for eoln
  111.         je    P2        ; if found here, error
  112.         stosb            ; OK - store al    to es:[di]
  113.         cmp    di,offset in_buffer
  114.         je    P2        ;  too many chars, exit    with error
  115.         jmp    Q2        ; repeat until done or error.
  116. Q3:        mov    al,5        ; success.
  117.  
  118. P3:        mov    byte ptr [di],0        ; null terminate the string
  119.         mov    di,offset last_line    ; reset    di
  120.         ret
  121.  
  122. P2:        mov    al,6        ; error    (non-success) code
  123.         jmp    P3
  124.  
  125. get_prefix    endp
  126.  
  127. ; --------------------------------------------------------------------------
  128. ;        SUBROUTINE  get_line
  129. ;        inputs a string    (line) from std    in
  130.  
  131. get_line    proc    near
  132.         mov    si,offset in_buffer    ; point    si to input buffer
  133.  
  134. G1:        mov    dx,si            ; point    dx to input buffer
  135.         mov    cx,1            ; set char count to 1
  136.         mov    bx,0            ; select handle    for input
  137.         mov    ah,03Fh            ; DOS input from std in
  138.         int    021h
  139.  
  140.         jc    getline_ret        ; error, code in ax
  141.         stc
  142.         mov    cx,ax            ; ax = chars read
  143.         jcxz    getline_ret        ; return if no chars read
  144.         cmp    byte ptr [si],0Ah    ; eoln,    return
  145.         je    getline_ret
  146.         cmp    byte ptr [si],01Ah    ; check    for eof
  147.         stc
  148.         jz    getline_ret        ; eof, ret w/carry set
  149.         inc    si            ; inc si
  150.         cmp    si,offset out_buffer    ; check    for buffer overrun
  151.         jb    G1            ; OK, repeat
  152.         stc                ; else,    ret w/carry set
  153.  
  154. getline_ret:    ret
  155.  
  156. get_line    endp
  157.  
  158. ; -------------------------------------------------------------------------
  159. ;        SUBROUTINE  set_prefix
  160. ;        prefixes the line that was input
  161.  
  162. set_prefix    proc    near
  163.         mov    di,offset out_buffer    ; point    di to output buffer
  164.  
  165. ; first    move the prefix    into the output    buffer:
  166.  
  167.         mov    si,offset last_line    ; restore prefix ptr to    si
  168. S1:
  169.         lodsb                ; [si] into al
  170.         cmp    al,0            ; end of prefix    (null term.)
  171.         je    S2
  172.         stosb                ; al to    es:[di]
  173.         jmp    S1            ; repeat
  174.  
  175. ; now move the input line into the output buffer:
  176.  
  177. S2:
  178.         mov    si,offset in_buffer    ; set si to line buffer
  179. S3:
  180.         lodsb                ; [si] into al
  181.         stosb                ; al to    es:[di]
  182.         cmp    al,0Ah            ; check    for eoln
  183.         jne    S3            ; repeat
  184.         ret                ; done - return
  185. set_prefix    endp
  186.  
  187. ; -------------------------------------------------------------------------
  188. ;        SUBROUTINE  out_put
  189. ;        outputs    the string (line) to std out
  190.  
  191. out_put        proc    near
  192.         mov    si,offset out_buffer    ; point    si to output buffer
  193.         mov    dx,si        ; put si in dx
  194.         xor    cx,cx        ; start    cx at 0
  195. O1:
  196.         inc    cx        ; pre-increment    for char count
  197.         cmp    cx,obuf_len    ; check    for buffer overrun
  198.         stc
  199.         jge    output_ret    ; prefix + line    too long, exit
  200.         lodsb            ; [si] into al
  201.         cmp    al,0Ah        ; see if it's eoln
  202.         jne    O1        ; if not, repeat.
  203.         mov    bx,1        ; set up std out
  204.         mov    ah,040h        ; output cx characters.
  205.         int    021h
  206. output_ret:    ret            ; carry set if error.
  207.  
  208. out_put        endp
  209.  
  210. ; -------------------------------------------------------------------------
  211. ;        SUBROUTINE  rem_space
  212. ;        eats up    blanks
  213.  
  214. rem_space    proc    near
  215. R1:
  216.         cmp    byte ptr [si],020h
  217.         jne    rem_space_ret
  218.         inc    si
  219.         jmp    R1
  220.  
  221. rem_space_ret:    ret
  222. rem_space    endp
  223.  
  224. ; --------------------------------------------------------------------------
  225. ;  buffer allocation:
  226.  
  227. last_line    label    byte    ; marks start of buffers area
  228.  
  229. in_buffer       =       last_line + pfx_len
  230. out_buffer      =       in_buffer + ibuf_len
  231. pgm_end         =       out_buffer + obuf_len + stk_len
  232.  
  233. codeseg        ends
  234.         end    start
  235.